package com.rc.web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.google.common.collect.ImmutableMap;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rc.common.constant.Code;
import com.rc.common.exception.BusinessException;
import com.rc.common.properties.WechatProperties;
import com.rc.pojo.po.Consumer;
import com.rc.pojo.po.IntegralDetail;
import com.rc.pojo.vo.consumer.ConsumerLoginVO;
import com.rc.pojo.vo.consumer.ConsumerVO;
import com.rc.web.converter.ConsumerConverter;
import com.rc.web.mapper.ConsumerMapper;
import com.rc.web.service.ConsumerService;
import com.rc.web.service.IntegralDetailService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Map;

/**
 * 移动端用户服务实现类
 * 提供用户相关的业务逻辑实现
 */
@Service
@RequiredArgsConstructor
public class ConsumerServiceImpl extends ServiceImpl<ConsumerMapper, Consumer> implements ConsumerService {
    // 用户转换器
    private final ConsumerConverter consumerConverter;
    // 微信配置属性
    private final WechatProperties wechatProperties;
    // REST模板
    private final RestTemplate restTemplate;
    // 积分明细服务
    private final IntegralDetailService integralDetailService;

    /**
     * 用户登录
     * @param code 微信登录code
     * @return 用户登录VO
     */
    @Override
    public ConsumerLoginVO login(String code) {
        // 构建微信登录请求参数
        Map<String,String> params = ImmutableMap.<String,String>builder()
                .put("appid", wechatProperties.getAppid())
                .put("secret", wechatProperties.getSecret())
                .put("js_code", code)
                .build();

        // 调用微信API获取openid
        Row response = restTemplate.getForObject(wechatProperties.getUrl(), Row.class,params);

        String openId = response.getString("openid");

        // 检查openid是否获取成功
        if (openId == null){
            throw new BusinessException(Code.CODE_ERROR);
        }

        // 根据openid查询用户
        Consumer consumer = mapper.selectByOpenId(openId);
        if (consumer == null){
            // 如果用户不存在则创建新用户
            consumer = Consumer.builder()
                    .openId(openId)
                    .build();
            this.save(consumer);
        }

        // 用户登录
        StpUtil.login(consumer.getId());
        StpUtil.getSession().set("consumer", consumer);
        ConsumerLoginVO vo = consumerConverter.toLoginVO(consumer);
        vo.setToken(StpUtil.getTokenValue());

        // 检查是否为今日首次登录
        LocalDate updateTime = consumer.getUpdateTime().toLocalDate();
        LocalDate now = LocalDate.now();
        if (updateTime.isBefore(now)) {
            // 如果是首次登录则增加积分
            IntegralDetail integralDetail = IntegralDetail.builder()
                    .title("每日登录")
                    .integral(10)
                    .build();
            integralDetailService.save(integralDetail);
            this.updateById(consumer);
        }
        return vo;
    }

    /**
     * 获取用户信息
     * @return 用户VO
     */
    @Override
    public ConsumerVO getInfo() {
        Consumer consumer = StpUtil.getSession().getModel("consumer", Consumer.class);
        return consumerConverter.toVO(consumer);
    }

    /**
     * 扣除用户余额
     * @param amount 扣除金额
     */
    @Override
    public void deductMoney(BigDecimal amount) {
        long loginId = StpUtil.getLoginIdAsLong();
        Consumer consumer = mapper.selectOneById(loginId);

        // 检查余额是否充足
        BigDecimal balance = consumer.getBalance();
        if (balance.compareTo(amount) < 0) {
            throw new BusinessException(Code.INSUFFICIENT_BALANCE);
        }

        // 扣除余额并更新用户信息
        consumer.setBalance(balance.subtract(amount));
        this.updateById(consumer);
        StpUtil.getSession().set("consumer", consumer);
    }
}
